package org.wisigoth.chat.client;

import java.util.Collection;

import org.wisigoth.chat.client.exceptions.AuthenticationException;
import org.wisigoth.chat.client.exceptions.ConnectionException;
import org.wisigoth.chat.client.exceptions.FriendListException;
import org.wisigoth.chat.client.exceptions.MessageException;

/**
 * <p>
 * A Session object is created by a call to
 * {@link Wisigoth#authenticate(String, char[])} if the connection parameters
 * are valid. The session object is initialized in the
 * {@link ConnectionState#ONLINE} state if the authentication succeed.
 * </p>
 * A session object is in {@link ConnectionState#ONLINE} state until a
 * connection problem occurs, or a server timeout occurs in case of a too long
 * idle period. If the session object is set to {@link ConnectionState#OFFLINE}
 * state for one of the above reasons, the session last for a period defined by
 * the server. While in ConnectionState.OFFLINE state and the connection to the
 * server is defective, the call to Session.connect() will throw a
 * ConnectionException. While in ConnectionState.OFFLINE state and the
 * connection to the server is available, the call to Session.connect(): -
 * reconnect to Wisigoth if the session is still valid - throw a
 * AuthenticationException if the session expired
 * 
 * @author dtfs-tof
 * 
 */
public interface Session {

	public static enum ConnectionState {
		ONLINE, OFFLINE
	}

	/**
	 * This method tries to authenticate a user from its username and password.
	 * If login or password are invalid, it throws an AuthenticationException.
	 * If authentication is successful, the connectionState is set to
	 * {@link ConnectionState#ONLINE} If the method is called while the
	 * connectionState is in ConnectionState.ONLINE state, nothing should
	 * occurs.
	 * 
	 * @param login
	 *            the user login
	 * @param password
	 *            the user password
	 * @return a non null Session object
	 * @throws AuthenticationException
	 *             if the user login or password are invalid
	 * @throws ConnectionException
	 *             if a connection problem occurs (Runtime)
	 */
	public void authenticate(String login, char[] password)
			throws AuthenticationException, ConnectionException;

	/**
	 * Open a chat session with a given contact
	 * 
	 * @param {@link Contact}
	 * @return {@link ChatSession}
	 */
	public ChatSession openChat(Contact contact);
	/**
	 * Close a given ChatSession
	 */
	public void closeChat(ChatSession chatSession);

	public Conference openConference(Collection<Contact> contactList);

	/**
	 * Modify the presence state of the Session
	 * 
	 * @param {@link Presence}
	 */
	public void setPresence(Presence presence);

	/**
	 * Return the presence state of the Session
	 * 
	 * @return Presence
	 */
	public Presence getPresence();

	/**
	 * Return the Wisigoth which creates the Session
	 * 
	 * @return {@link Wisigoth}
	 */
	public Wisigoth getWisigoth();


	public void addPresenceListener(PresenceListener e);

	public void removePresenceListener(PresenceListener e);

	/**
	 * Return the ConnectionState of a Session
	 * 
	 * @return {@link ConnectionState}
	 */
	public ConnectionState getConnectionState();

	/**
	 * Connect to Wisigoth using previous session parameters. If session is
	 * already connected; nothing occurs. If not, connection state is set to
	 * {@link ConnectionState#ONLINE}
	 * 
	 * @throws AuthenticationException
	 * @throws ConnectionException
	 *             if a connection problem occurs (Runtime)
	 */
	public void reconnect() throws AuthenticationException, ConnectionException;

	/**
	 * Disconnect from Wisigoth. if the connection state was offline nothing
	 * occurs, if the connection state was online connection state is set to
	 * {@link ConnectionState#OFFLINE}. the session last, after deconnection,
	 * for a time determined by the server.
	 * 
	 * @throws ConnectionException
	 *             if the connection to the server is lost before the call
	 *             (Runtime)
	 */
	public void disconnect() throws ConnectionException;

	public void addConnectionStateListener(ConnectionStateListener listener);

	public void removeConnectionStateListener(ConnectionStateListener listener);

	/**
	 * Method called when the client user ends a Wisigoth session
	 */
	public void quitWisigoth();

	/**
	 * Send a message to the wisigoth server.
	 * 
	 * @param message
	 *            a message object
	 * @throws ConnectionException
	 *             if a connection problem occurs during sending of the message
	 * @throws MessageException
	 *             if the message is malformed or unrecognized by the server
	 */
	public void sendMessage(Message message) throws ConnectionException,
			MessageException;
	
	/**
	 * Allow to get the user currently connected to this session as a WisigothUser.
	 * IF Session is not already connected a ConnectionException is thrown.
	 *  
	 * @return my user
	 */
	public WisigothUser whoAmI() throws ConnectionException;

	/**
	 * Set the {@link ConnectionState}
	 * @param connState
	 */
	public void setConnectionState(ConnectionState connState);
	
	/**
	 * return the FriendList, the list of Contacts added to the friend list
	 * @return {@link FriendList}
	 * @throws FriendListException if the FriendList is null
	 */
	public FriendList getFriendList()throws FriendListException;

	/**
	 * set the friend list of the current session
	 */
	public void setFriendList();
	
	public void setUnconsumedMessageConsumer(MessageConsumer consumer);
	
	
	




}
